<!-- HTML header for doxygen 1.8.6-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.13"/>
<title>OpenCV: Color Correction Model</title>
<link href="../../opencv.ico" rel="shortcut icon" type="image/x-icon" />
<link href="../../tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="../../jquery.js"></script>
<script type="text/javascript" src="../../dynsections.js"></script>
<script type="text/javascript" src="../../tutorial-utils.js"></script>
<link href="../../search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="../../search/searchdata.js"></script>
<script type="text/javascript" src="../../search/search.js"></script>
<script type="text/x-mathjax-config">
  MathJax.Hub.Config({
    extensions: ["tex2jax.js", "TeX/AMSmath.js", "TeX/AMSsymbols.js"],
    jax: ["input/TeX","output/HTML-CSS"],
});
//<![CDATA[
MathJax.Hub.Config(
{
  TeX: {
      Macros: {
          matTT: [ "\\[ \\left|\\begin{array}{ccc} #1 & #2 & #3\\\\ #4 & #5 & #6\\\\ #7 & #8 & #9 \\end{array}\\right| \\]", 9],
          fork: ["\\left\\{ \\begin{array}{l l} #1 & \\mbox{#2}\\\\ #3 & \\mbox{#4}\\\\ \\end{array} \\right.", 4],
          forkthree: ["\\left\\{ \\begin{array}{l l} #1 & \\mbox{#2}\\\\ #3 & \\mbox{#4}\\\\ #5 & \\mbox{#6}\\\\ \\end{array} \\right.", 6],
          forkfour: ["\\left\\{ \\begin{array}{l l} #1 & \\mbox{#2}\\\\ #3 & \\mbox{#4}\\\\ #5 & \\mbox{#6}\\\\ #7 & \\mbox{#8}\\\\ \\end{array} \\right.", 8],
          vecthree: ["\\begin{bmatrix} #1\\\\ #2\\\\ #3 \\end{bmatrix}", 3],
          vecthreethree: ["\\begin{bmatrix} #1 & #2 & #3\\\\ #4 & #5 & #6\\\\ #7 & #8 & #9 \\end{bmatrix}", 9],
          cameramatrix: ["#1 = \\begin{bmatrix} f_x & 0 & c_x\\\\ 0 & f_y & c_y\\\\ 0 & 0 & 1 \\end{bmatrix}", 1],
          distcoeffs: ["(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6 [, s_1, s_2, s_3, s_4[, \\tau_x, \\tau_y]]]]) \\text{ of 4, 5, 8, 12 or 14 elements}"],
          distcoeffsfisheye: ["(k_1, k_2, k_3, k_4)"],
          hdotsfor: ["\\dots", 1],
          mathbbm: ["\\mathbb{#1}", 1],
          bordermatrix: ["\\matrix{#1}", 1]
      }
  }
}
);
//]]>
</script><script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js"></script>
<link href="../../doxygen.css" rel="stylesheet" type="text/css" />
<link href="../../stylesheet.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<!--#include virtual="/google-search.html"-->
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr style="height: 56px;">
  <td id="projectlogo"><img alt="Logo" src="../../opencv-logo-small.png"/></td>
  <td style="padding-left: 0.5em;">
   <div id="projectname">OpenCV
   &#160;<span id="projectnumber">4.5.2</span>
   </div>
   <div id="projectbrief">Open Source Computer Vision</div>
  </td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.13 -->
<script type="text/javascript">
var searchBox = new SearchBox("searchBox", "../../search",false,'Search');
</script>
<script type="text/javascript" src="../../menudata.js"></script>
<script type="text/javascript" src="../../menu.js"></script>
<script type="text/javascript">
$(function() {
  initMenu('../../',true,false,'search.php','Search');
  $(document).ready(function() { init_search(); });
});
</script>
<div id="main-nav"></div>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0" 
        name="MSearchResults" id="MSearchResults">
</iframe>
</div>

<div id="nav-path" class="navpath">
  <ul>
<li class="navelem"><a class="el" href="../../d3/d81/tutorial_contrib_root.html">Tutorials for contrib modules</a></li><li class="navelem"><a class="el" href="../../db/db3/tutorial_table_of_content_ccm.html">Color Correction Model</a></li>  </ul>
</div>
</div><!-- top -->
<div class="header">
  <div class="headertitle">
<div class="title">Color Correction Model </div>  </div>
</div><!--header-->
<div class="contents">
<div class="textblock"><p>In this tutorial you will learn how to use the 'Color Correction Model' to do a color correction in a image.</p>
<h2>Reference </h2>
<p>See details of ColorCorrection Algorithm at <a href="https://github.com/riskiest/color_calibration/tree/v4/doc/pdf/English/Algorithm">https://github.com/riskiest/color_calibration/tree/v4/doc/pdf/English/Algorithm</a></p>
<h2>Building </h2>
<p>When building OpenCV, run the following command to build all the contrib modules:</p>
<div class="fragment"><div class="line">cmake -D OPENCV_EXTRA_MODULES_PATH=&lt;opencv_contrib&gt;/modules/</div></div><!-- fragment --><p>Or only build the mcc module:</p>
<div class="fragment"><div class="line">cmake -D OPENCV_EXTRA_MODULES_PATH=&lt;opencv_contrib&gt;/modules/mcc</div></div><!-- fragment --><p>Or make sure you check the mcc module in the GUI version of CMake: cmake-gui.</p>
<h2>Source Code of the sample </h2>
<p>The sample has two parts of code, the first is the color checker detector model, see details at <a class="el" href="../../d9/d7e/tutorial_mcc_basic_chart_detection.html">Detecting colorcheckers using basic algorithms</a>, the second part is to make collor calibration.</p>
<div class="fragment"><div class="line">Here are the parameters for ColorCorrectionModel</div><div class="line">    src :</div><div class="line">            detected colors of ColorChecker patches;</div><div class="line">            NOTICE: the color type is RGB not BGR, and the color values are in [0, 1];</div><div class="line">    constcolor :</div><div class="line">            the Built-in color card;</div><div class="line">            Supported list:</div><div class="line">                Macbeth: Macbeth ColorChecker ;</div><div class="line">                Vinyl: DKK ColorChecker ;</div><div class="line">                DigitalSG: DigitalSG ColorChecker with 140 squares;</div><div class="line">    Mat colors :</div><div class="line">           the reference color values</div><div class="line">           and corresponding color space</div><div class="line">           NOTICE: the color values are in [0, 1]</div><div class="line">    ref_cs :</div><div class="line">           the corresponding color space</div><div class="line">                  If the color type is some RGB, the format is RGB not BGR;</div><div class="line">    Supported Color Space:</div><div class="line">            Supported list of RGB color spaces:</div><div class="line">                COLOR_SPACE_sRGB;</div><div class="line">                COLOR_SPACE_AdobeRGB;</div><div class="line">                COLOR_SPACE_WideGamutRGB;</div><div class="line">                COLOR_SPACE_ProPhotoRGB;</div><div class="line">                COLOR_SPACE_DCI_P3_RGB;</div><div class="line">                COLOR_SPACE_AppleRGB;</div><div class="line">                COLOR_SPACE_REC_709_RGB;</div><div class="line">                COLOR_SPACE_REC_2020_RGB;</div><div class="line">            Supported list of linear RGB color spaces:</div><div class="line">                COLOR_SPACE_sRGBL;</div><div class="line">                COLOR_SPACE_AdobeRGBL;</div><div class="line">                COLOR_SPACE_WideGamutRGBL;</div><div class="line">                COLOR_SPACE_ProPhotoRGBL;</div><div class="line">                COLOR_SPACE_DCI_P3_RGBL;</div><div class="line">                COLOR_SPACE_AppleRGBL;</div><div class="line">                COLOR_SPACE_REC_709_RGBL;</div><div class="line">                COLOR_SPACE_REC_2020_RGBL;</div><div class="line">            Supported list of non-RGB color spaces:</div><div class="line">                COLOR_SPACE_Lab_D50_2;</div><div class="line">                COLOR_SPACE_Lab_D65_2;</div><div class="line">                COLOR_SPACE_XYZ_D50_2;</div><div class="line">                COLOR_SPACE_XYZ_D65_2;</div><div class="line">                COLOR_SPACE_XYZ_D65_10;</div><div class="line">                COLOR_SPACE_XYZ_D50_10;</div><div class="line">                COLOR_SPACE_XYZ_A_2;</div><div class="line">                COLOR_SPACE_XYZ_A_10;</div><div class="line">                COLOR_SPACE_XYZ_D55_2;</div><div class="line">                COLOR_SPACE_XYZ_D55_10;</div><div class="line">                COLOR_SPACE_XYZ_D75_2;</div><div class="line">                COLOR_SPACE_XYZ_D75_10;</div><div class="line">                COLOR_SPACE_XYZ_E_2;</div><div class="line">                COLOR_SPACE_XYZ_E_10;</div><div class="line">                COLOR_SPACE_Lab_D65_10;</div><div class="line">                COLOR_SPACE_Lab_D50_10;</div><div class="line">                COLOR_SPACE_Lab_A_2;</div><div class="line">                COLOR_SPACE_Lab_A_10;</div><div class="line">                COLOR_SPACE_Lab_D55_2;</div><div class="line">                COLOR_SPACE_Lab_D55_10;</div><div class="line">                COLOR_SPACE_Lab_D75_2;</div><div class="line">                COLOR_SPACE_Lab_D75_10;</div><div class="line">                COLOR_SPACE_Lab_E_2;</div><div class="line">                COLOR_SPACE_Lab_E_10;</div></div><!-- fragment --><h2>Code</h2>
<div class="fragment"><div class="line"><span class="preprocessor">#include &lt;<a class="code" href="../../d0/d9c/core_2include_2opencv2_2core_8hpp.html">opencv2/core.hpp</a>&gt;</span></div><div class="line"></div><div class="line"><span class="preprocessor">#include &lt;<a class="code" href="../../d4/dd5/highgui_8hpp.html">opencv2/highgui.hpp</a>&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;<a class="code" href="../../d6/d87/imgcodecs_8hpp.html">opencv2/imgcodecs.hpp</a>&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;<a class="code" href="../../df/d35/mcc_8hpp.html">opencv2/mcc.hpp</a>&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;iostream&gt;</span></div><div class="line"></div><div class="line"><span class="keyword">using namespace </span>std;</div><div class="line"><span class="keyword">using namespace </span><a class="code" href="../../d2/d75/namespacecv.html">cv</a>;</div><div class="line"><span class="keyword">using namespace </span>mcc;</div><div class="line"><span class="keyword">using namespace </span>ccm;</div><div class="line"><span class="keyword">using namespace </span>std;</div><div class="line"></div><div class="line"><span class="keyword">const</span> <span class="keywordtype">char</span> *about = <span class="stringliteral">&quot;Basic chart detection&quot;</span>;</div><div class="line"><span class="keyword">const</span> <span class="keywordtype">char</span> *keys =</div><div class="line">    <span class="stringliteral">&quot;{ help h  |    | show this message }&quot;</span></div><div class="line">    <span class="stringliteral">&quot;{t        |      |  chartType: 0-Standard, 1-DigitalSG, 2-Vinyl }&quot;</span></div><div class="line">    <span class="stringliteral">&quot;{v        |      | Input from video file, if ommited, input comes from camera }&quot;</span></div><div class="line">    <span class="stringliteral">&quot;{ci       | 0    | Camera id if input doesnt come from video (-v) }&quot;</span></div><div class="line">    <span class="stringliteral">&quot;{f        | 1    | Path of the file to process (-v) }&quot;</span></div><div class="line">    <span class="stringliteral">&quot;{nc       | 1    | Maximum number of charts in the image }&quot;</span>;</div><div class="line"></div><div class="line"><span class="keywordtype">int</span> main(<span class="keywordtype">int</span> argc, <span class="keywordtype">char</span> *argv[])</div><div class="line">{</div><div class="line"></div><div class="line"></div><div class="line">    <span class="comment">// ----------------------------------------------------------</span></div><div class="line">    <span class="comment">// Scroll down a bit (~40 lines) to find actual relevant code</span></div><div class="line">    <span class="comment">// ----------------------------------------------------------</span></div><div class="line"><span class="comment"></span>    <a class="code" href="../../d0/d2e/classcv_1_1CommandLineParser.html">CommandLineParser</a> parser(argc, argv, keys);</div><div class="line">    parser.about(about);</div><div class="line">    <span class="keywordflow">if</span> (argc==1 || parser.has(<span class="stringliteral">&quot;help&quot;</span>))</div><div class="line">    {</div><div class="line">        parser.printMessage();</div><div class="line">        <span class="keywordflow">return</span> 0;</div><div class="line">    }</div><div class="line"></div><div class="line">    <span class="keywordtype">int</span> t = parser.get&lt;<span class="keywordtype">int</span>&gt;(<span class="stringliteral">&quot;t&quot;</span>);</div><div class="line">    <span class="keywordtype">int</span> nc = parser.get&lt;<span class="keywordtype">int</span>&gt;(<span class="stringliteral">&quot;nc&quot;</span>);</div><div class="line">    <span class="keywordtype">string</span> filepath = parser.get&lt;<span class="keywordtype">string</span>&gt;(<span class="stringliteral">&quot;f&quot;</span>);</div><div class="line"></div><div class="line">    <a class="code" href="../../db/de0/group__core__utils.html#gaf62bcd90f70e275191ab95136d85906b">CV_Assert</a>(0 &lt;= t &amp;&amp; t &lt;= 2);</div><div class="line">    <a class="code" href="../../dd/d19/group__mcc.html#ga836ee96afcefd4f35e95760ca9e8163d">TYPECHART</a> chartType = <a class="code" href="../../dd/d19/group__mcc.html#ga836ee96afcefd4f35e95760ca9e8163d">TYPECHART</a>(t);</div><div class="line"></div><div class="line"></div><div class="line">    <span class="keywordflow">if</span> (!parser.check())</div><div class="line">    {</div><div class="line">        parser.printErrors();</div><div class="line">        <span class="keywordflow">return</span> 0;</div><div class="line">    }</div><div class="line"></div><div class="line">    <a class="code" href="../../d3/d63/classcv_1_1Mat.html">Mat</a> image = <a class="code" href="../../d4/da8/group__imgcodecs.html#ga288b8b3da0892bd651fce07b3bbd3a56">imread</a>(filepath, <a class="code" href="../../d8/d6a/group__imgcodecs__flags.html#gga61d9b0126a3e57d9277ac48327799c80af660544735200cbe942eea09232eb822">IMREAD_COLOR</a>);</div><div class="line">    <span class="keywordflow">if</span> (!image.<a class="code" href="../../d3/d63/classcv_1_1Mat.html#a4d33bed1c850265370d2af0ff02e1564">data</a>)</div><div class="line">    {</div><div class="line">        cout &lt;&lt; <span class="stringliteral">&quot;Invalid Image!&quot;</span> &lt;&lt; endl;</div><div class="line">        <span class="keywordflow">return</span> 1;</div><div class="line">    }</div><div class="line"></div><div class="line">    <a class="code" href="../../d3/d63/classcv_1_1Mat.html">Mat</a> imageCopy = image.<a class="code" href="../../d3/d63/classcv_1_1Mat.html#adff2ea98da45eae0833e73582dd4a660">clone</a>();</div><div class="line">    <a class="code" href="../../dc/d84/group__core__basic.html#ga6395ca871a678020c4a31fadf7e8cc63">Ptr&lt;CCheckerDetector&gt;</a> detector = CCheckerDetector::create();</div><div class="line">    <span class="comment">// Marker type to detect</span></div><div class="line">    <span class="keywordflow">if</span> (!detector-&gt;process(image, chartType, nc))</div><div class="line">    {</div><div class="line">        printf(<span class="stringliteral">&quot;ChartColor not detected \n&quot;</span>);</div><div class="line">        <span class="keywordflow">return</span> 2;</div><div class="line">    }</div><div class="line">    vector&lt;Ptr&lt;mcc::CChecker&gt;&gt; checkers = detector-&gt;getListColorChecker();</div><div class="line">    <span class="keywordflow">for</span> (<a class="code" href="../../dc/d84/group__core__basic.html#ga6395ca871a678020c4a31fadf7e8cc63">Ptr&lt;mcc::CChecker&gt;</a> checker : checkers)</div><div class="line">    {</div><div class="line">        <a class="code" href="../../dc/d84/group__core__basic.html#ga6395ca871a678020c4a31fadf7e8cc63">Ptr&lt;CCheckerDraw&gt;</a> cdraw = CCheckerDraw::create(checker);</div><div class="line">        cdraw-&gt;draw(image);</div><div class="line">        <a class="code" href="../../d3/d63/classcv_1_1Mat.html">Mat</a> chartsRGB = checker-&gt;getChartsRGB();</div><div class="line">        <a class="code" href="../../d3/d63/classcv_1_1Mat.html">Mat</a> src = chartsRGB.<a class="code" href="../../d3/d63/classcv_1_1Mat.html#a23df02a07ffbfa4aa59c19bc003919fe">col</a>(1).<a class="code" href="../../d3/d63/classcv_1_1Mat.html#adff2ea98da45eae0833e73582dd4a660">clone</a>().<a class="code" href="../../d3/d63/classcv_1_1Mat.html#a4eb96e3251417fa88b78e2abd6cfd7d8">reshape</a>(3, chartsRGB.<a class="code" href="../../d3/d63/classcv_1_1Mat.html#abed816466c45234254d25bc59c31245e">rows</a>/3);</div><div class="line">        src /= 255.0;</div><div class="line"></div><div class="line">        <span class="comment">//compte color correction matrix</span></div><div class="line"><span class="comment"></span>        ColorCorrectionModel model1(src, <a class="code" href="../../de/df4/group__color__correction.html#gga9550427e0c935010355bbbd7d4569836a35bd21ec824969dc661faee733d6fd20">COLORCHECKER_Vinyl</a>);</div><div class="line">        model1.run();</div><div class="line">        <a class="code" href="../../d3/d63/classcv_1_1Mat.html">Mat</a> ccm = model1.getCCM();</div><div class="line">        std::cout&lt;&lt;<span class="stringliteral">&quot;ccm &quot;</span>&lt;&lt;ccm&lt;&lt;std::endl;</div><div class="line">        <span class="keywordtype">double</span> loss = model1.getLoss();</div><div class="line">        std::cout&lt;&lt;<span class="stringliteral">&quot;loss &quot;</span>&lt;&lt;loss&lt;&lt;std::endl;</div><div class="line">         <span class="comment">/* brief More models with different parameters, try it &amp; check the document for details.</span></div><div class="line"><span class="comment">        */</span></div><div class="line">        <span class="comment">// model1.setColorSpace(COLOR_SPACE_sRGB);</span></div><div class="line">        <span class="comment">// model1.setCCM_TYPE(CCM_3x3);</span></div><div class="line">        <span class="comment">// model1.setDistance(DISTANCE_CIE2000);</span></div><div class="line">        <span class="comment">// model1.setLinear(LINEARIZATION_GAMMA);</span></div><div class="line">        <span class="comment">// model1.setLinearGamma(2.2);</span></div><div class="line">        <span class="comment">// model1.setLinearDegree(3);</span></div><div class="line">        <span class="comment">// model1.setSaturatedThreshold(0, 0.98);</span></div><div class="line"></div><div class="line">        <span class="comment">/* If you use a customized ColorChecker, you can use your own reference color values and corresponding color space in a way like:</span></div><div class="line"><span class="comment">        */</span></div><div class="line">        <span class="comment">// cv::Mat ref = (Mat_&lt;Vec3d&gt;(18, 1) &lt;&lt;</span></div><div class="line">        <span class="comment">// Vec3d(100, 0.00520000001, -0.0104),</span></div><div class="line">        <span class="comment">// Vec3d(73.0833969, -0.819999993, -2.02099991),</span></div><div class="line">        <span class="comment">// Vec3d(62.493, 0.425999999, -2.23099995),</span></div><div class="line">        <span class="comment">// Vec3d(50.4640007, 0.446999997, -2.32399988),</span></div><div class="line">        <span class="comment">// Vec3d(37.7970009, 0.0359999985, -1.29700005),</span></div><div class="line">        <span class="comment">// Vec3d(0, 0, 0),</span></div><div class="line">        <span class="comment">// Vec3d(51.5880013, 73.5179977, 51.5690002),</span></div><div class="line">        <span class="comment">// Vec3d(93.6989975, -15.7340002, 91.9420013),</span></div><div class="line">        <span class="comment">// Vec3d(69.4079971, -46.5940018, 50.4869995),</span></div><div class="line">        <span class="comment">// Vec3d(66.61000060000001, -13.6789999, -43.1720009),</span></div><div class="line">        <span class="comment">// Vec3d(11.7110004, 16.9799995, -37.1759987),</span></div><div class="line">        <span class="comment">// Vec3d(51.973999, 81.9440002, -8.40699959),</span></div><div class="line">        <span class="comment">// Vec3d(40.5489998, 50.4399986, 24.8490009),</span></div><div class="line">        <span class="comment">// Vec3d(60.8160019, 26.0690002, 49.4420013),</span></div><div class="line">        <span class="comment">// Vec3d(52.2529984, -19.9500008, -23.9960003),</span></div><div class="line">        <span class="comment">// Vec3d(51.2859993, 48.4700012, -15.0579996),</span></div><div class="line">        <span class="comment">// Vec3d(68.70700069999999, 12.2959995, 16.2129993),</span></div><div class="line">        <span class="comment">// Vec3d(63.6839981, 10.2930002, 16.7639999));</span></div><div class="line"></div><div class="line">        <span class="comment">// ColorCorrectionModel model8(src,ref,COLOR_SPACE_Lab_D50_2);</span></div><div class="line">        <span class="comment">// model8.run();</span></div><div class="line"><span class="comment"></span></div><div class="line">        <a class="code" href="../../d3/d63/classcv_1_1Mat.html">Mat</a> img_;</div><div class="line">        <a class="code" href="../../d8/d01/group__imgproc__color__conversions.html#ga397ae87e1288a81d2363b61574eb8cab">cvtColor</a>(image, img_, <a class="code" href="../../d8/d01/group__imgproc__color__conversions.html#gga4e0972be5de079fed4e3a10e24ef5ef0ad3db9ff253b87d02efe4887b2f5d77ee">COLOR_BGR2RGB</a>);</div><div class="line">        img_.<a class="code" href="../../d3/d63/classcv_1_1Mat.html#adf88c60c5b4980e05bb556080916978b">convertTo</a>(img_, <a class="code" href="../../d1/d1b/group__core__hal__interface.html#ga30a562691cc5987bc88eb7bb7a8faf2b">CV_64F</a>);</div><div class="line">        <span class="keyword">const</span> <span class="keywordtype">int</span> inp_size = 255;</div><div class="line">        <span class="keyword">const</span> <span class="keywordtype">int</span> out_size = 255;</div><div class="line">        img_ = img_ / inp_size;</div><div class="line">        <a class="code" href="../../d3/d63/classcv_1_1Mat.html">Mat</a> calibratedImage= model1.infer(img_);</div><div class="line">        <a class="code" href="../../d3/d63/classcv_1_1Mat.html">Mat</a> out_ = calibratedImage * out_size;</div><div class="line"></div><div class="line">        <span class="comment">// Save the calibrated image to {FILE_NAME}.calibrated.{FILE_EXT}</span></div><div class="line">        out_.<a class="code" href="../../d3/d63/classcv_1_1Mat.html#adf88c60c5b4980e05bb556080916978b">convertTo</a>(out_, <a class="code" href="../../d1/d1b/group__core__hal__interface.html#ga88c4cd9de76f678f33928ef1e3f96047">CV_8UC3</a>);</div><div class="line">        <a class="code" href="../../d3/d63/classcv_1_1Mat.html">Mat</a> img_out = <a class="code" href="../../d7/dcc/group__core__utils__softfloat.html#gac48df53b8fd34b87e7b121fa8fd4c379">min</a>(<a class="code" href="../../d7/dcc/group__core__utils__softfloat.html#ga78f988f6cfa6223610298cbd4f86ec66">max</a>(out_, 0), out_size);</div><div class="line">        <a class="code" href="../../d3/d63/classcv_1_1Mat.html">Mat</a> out_img;</div><div class="line">        <a class="code" href="../../d8/d01/group__imgproc__color__conversions.html#ga397ae87e1288a81d2363b61574eb8cab">cvtColor</a>(img_out, out_img, <a class="code" href="../../d8/d01/group__imgproc__color__conversions.html#gga4e0972be5de079fed4e3a10e24ef5ef0a01a06e50cd3689f5e34e26daf3faaa39">COLOR_RGB2BGR</a>);</div><div class="line">        <span class="keywordtype">string</span> filename = filepath.substr(filepath.find_last_of(<span class="charliteral">&#39;/&#39;</span>)+1);</div><div class="line">        <span class="keywordtype">size_t</span> dotIndex = filename.find_last_of(<span class="charliteral">&#39;.&#39;</span>);</div><div class="line">        <span class="keywordtype">string</span> baseName = filename.substr(0, dotIndex);</div><div class="line">        <span class="keywordtype">string</span> ext = filename.substr(dotIndex+1, filename.length()-dotIndex);</div><div class="line">        <span class="keywordtype">string</span> calibratedFilePath = baseName + <span class="stringliteral">&quot;.calibrated.&quot;</span> + ext;</div><div class="line">        <a class="code" href="../../d4/da8/group__imgcodecs.html#gabbc7ef1aa2edfaa87772f1202d67e0ce">imwrite</a>(calibratedFilePath, out_img);</div><div class="line"></div><div class="line">    }</div><div class="line"></div><div class="line">    <span class="keywordflow">return</span> 0;</div><div class="line">}</div></div><!-- fragment --> <h2>Explanation</h2>
<p>The first part is to detect the ColorChecker position. </p><div class="fragment"><div class="line">    vector&lt;Ptr&lt;mcc::CChecker&gt;&gt; checkers = detector-&gt;getListColorChecker();</div></div><!-- fragment --><div class="fragment"><div class="line">    CommandLineParser parser(argc, argv, keys);</div><div class="line">    parser.about(about);</div><div class="line">    <span class="keywordflow">if</span> (argc==1 || parser.has(<span class="stringliteral">&quot;help&quot;</span>))</div><div class="line">    {</div><div class="line">        parser.printMessage();</div><div class="line">        <span class="keywordflow">return</span> 0;</div><div class="line">    }</div><div class="line"></div><div class="line">    <span class="keywordtype">int</span> t = parser.get&lt;<span class="keywordtype">int</span>&gt;(<span class="stringliteral">&quot;t&quot;</span>);</div><div class="line">    <span class="keywordtype">int</span> nc = parser.get&lt;<span class="keywordtype">int</span>&gt;(<span class="stringliteral">&quot;nc&quot;</span>);</div><div class="line">    <span class="keywordtype">string</span> filepath = parser.get&lt;<span class="keywordtype">string</span>&gt;(<span class="stringliteral">&quot;f&quot;</span>);</div><div class="line"></div><div class="line">    <a class="code" href="../../db/de0/group__core__utils.html#gaf62bcd90f70e275191ab95136d85906b">CV_Assert</a>(0 &lt;= t &amp;&amp; t &lt;= 2);</div><div class="line">    <a class="code" href="../../dd/d19/group__mcc.html#ga836ee96afcefd4f35e95760ca9e8163d">TYPECHART</a> chartType = <a class="code" href="../../dd/d19/group__mcc.html#ga836ee96afcefd4f35e95760ca9e8163d">TYPECHART</a>(t);</div><div class="line"></div><div class="line"></div><div class="line">    <span class="keywordflow">if</span> (!parser.check())</div><div class="line">    {</div><div class="line">        parser.printErrors();</div><div class="line">        <span class="keywordflow">return</span> 0;</div><div class="line">    }</div><div class="line"></div><div class="line">    Mat image = <a class="code" href="../../d4/da8/group__imgcodecs.html#ga288b8b3da0892bd651fce07b3bbd3a56">imread</a>(filepath, <a class="code" href="../../d8/d6a/group__imgcodecs__flags.html#gga61d9b0126a3e57d9277ac48327799c80af660544735200cbe942eea09232eb822">IMREAD_COLOR</a>);</div><div class="line">    <span class="keywordflow">if</span> (!image.data)</div><div class="line">    {</div><div class="line">        cout &lt;&lt; <span class="stringliteral">&quot;Invalid Image!&quot;</span> &lt;&lt; endl;</div><div class="line">        <span class="keywordflow">return</span> 1;</div><div class="line">    }</div></div><!-- fragment --><p>Preparation for ColorChecker detection to get messages for the image.</p>
<div class="fragment"><div class="line">        Ptr&lt;CCheckerDraw&gt; cdraw = CCheckerDraw::create(checker);</div><div class="line">        cdraw-&gt;draw(image);</div><div class="line">        Mat chartsRGB = checker-&gt;getChartsRGB();</div><div class="line">        Mat src = chartsRGB.<a class="code" href="../../d3/d63/classcv_1_1Mat.html#a23df02a07ffbfa4aa59c19bc003919fe">col</a>(1).<a class="code" href="../../d3/d63/classcv_1_1Mat.html#adff2ea98da45eae0833e73582dd4a660">clone</a>().<a class="code" href="../../d3/d63/classcv_1_1Mat.html#a4eb96e3251417fa88b78e2abd6cfd7d8">reshape</a>(3, chartsRGB.rows/3);</div><div class="line">        src /= 255.0;</div></div><!-- fragment --><p>The CCheckerDetectorobject is created and uses getListColorChecker function to get ColorChecker message.</p>
<div class="fragment"><div class="line">        ColorCorrectionModel model1(src, <a class="code" href="../../de/df4/group__color__correction.html#gga9550427e0c935010355bbbd7d4569836a35bd21ec824969dc661faee733d6fd20">COLORCHECKER_Vinyl</a>);</div><div class="line">        model1.run();</div><div class="line">        Mat ccm = model1.getCCM();</div><div class="line">        std::cout&lt;&lt;<span class="stringliteral">&quot;ccm &quot;</span>&lt;&lt;ccm&lt;&lt;std::endl;</div><div class="line">        <span class="keywordtype">double</span> loss = model1.getLoss();</div><div class="line">        std::cout&lt;&lt;<span class="stringliteral">&quot;loss &quot;</span>&lt;&lt;loss&lt;&lt;std::endl;</div></div><!-- fragment --><p>For every ColorChecker, we can compute a ccm matrix for color correction. Model1 is an object of ColorCorrectionModel class. The parameters should be changed to get the best effect of color correction. See other parameters' detail at the Parameters.</p>
<div class="fragment"><div class="line">        <span class="comment">// cv::Mat ref = (Mat_&lt;Vec3d&gt;(18, 1) &lt;&lt;</span></div><div class="line">        <span class="comment">// Vec3d(100, 0.00520000001, -0.0104),</span></div><div class="line">        <span class="comment">// Vec3d(73.0833969, -0.819999993, -2.02099991),</span></div><div class="line">        <span class="comment">// Vec3d(62.493, 0.425999999, -2.23099995),</span></div><div class="line">        <span class="comment">// Vec3d(50.4640007, 0.446999997, -2.32399988),</span></div><div class="line">        <span class="comment">// Vec3d(37.7970009, 0.0359999985, -1.29700005),</span></div><div class="line">        <span class="comment">// Vec3d(0, 0, 0),</span></div><div class="line">        <span class="comment">// Vec3d(51.5880013, 73.5179977, 51.5690002),</span></div><div class="line">        <span class="comment">// Vec3d(93.6989975, -15.7340002, 91.9420013),</span></div><div class="line">        <span class="comment">// Vec3d(69.4079971, -46.5940018, 50.4869995),</span></div><div class="line">        <span class="comment">// Vec3d(66.61000060000001, -13.6789999, -43.1720009),</span></div><div class="line">        <span class="comment">// Vec3d(11.7110004, 16.9799995, -37.1759987),</span></div><div class="line">        <span class="comment">// Vec3d(51.973999, 81.9440002, -8.40699959),</span></div><div class="line">        <span class="comment">// Vec3d(40.5489998, 50.4399986, 24.8490009),</span></div><div class="line">        <span class="comment">// Vec3d(60.8160019, 26.0690002, 49.4420013),</span></div><div class="line">        <span class="comment">// Vec3d(52.2529984, -19.9500008, -23.9960003),</span></div><div class="line">        <span class="comment">// Vec3d(51.2859993, 48.4700012, -15.0579996),</span></div><div class="line">        <span class="comment">// Vec3d(68.70700069999999, 12.2959995, 16.2129993),</span></div><div class="line">        <span class="comment">// Vec3d(63.6839981, 10.2930002, 16.7639999));</span></div><div class="line"></div><div class="line">        <span class="comment">// ColorCorrectionModel model8(src,ref,COLOR_SPACE_Lab_D50_2);</span></div><div class="line">        <span class="comment">// model8.run();</span></div></div><!-- fragment --><p>If you use a customized ColorChecker, you can use your own reference color values and corresponding color space as shown above.</p>
<div class="fragment"><div class="line">        Mat img_;</div><div class="line">        <a class="code" href="../../d8/d01/group__imgproc__color__conversions.html#ga397ae87e1288a81d2363b61574eb8cab">cvtColor</a>(image, img_, <a class="code" href="../../d8/d01/group__imgproc__color__conversions.html#gga4e0972be5de079fed4e3a10e24ef5ef0ad3db9ff253b87d02efe4887b2f5d77ee">COLOR_BGR2RGB</a>);</div><div class="line">        img_.convertTo(img_, <a class="code" href="../../d1/d1b/group__core__hal__interface.html#ga30a562691cc5987bc88eb7bb7a8faf2b">CV_64F</a>);</div><div class="line">        <span class="keyword">const</span> <span class="keywordtype">int</span> inp_size = 255;</div><div class="line">        <span class="keyword">const</span> <span class="keywordtype">int</span> out_size = 255;</div><div class="line">        img_ = img_ / inp_size;</div><div class="line">        Mat calibratedImage= model1.infer(img_);</div><div class="line">        Mat out_ = calibratedImage * out_size;</div></div><!-- fragment --><p>The member function infer_image is to make correction correction using ccm matrix.</p>
<div class="fragment"><div class="line">        <span class="comment">// Save the calibrated image to {FILE_NAME}.calibrated.{FILE_EXT}</span></div><div class="line">        out_.convertTo(out_, <a class="code" href="../../d1/d1b/group__core__hal__interface.html#ga88c4cd9de76f678f33928ef1e3f96047">CV_8UC3</a>);</div><div class="line">        Mat img_out = <a class="code" href="../../d1/d10/classcv_1_1MatExpr.html#ac22d7d32f1ec91fd106760a98a6f4731">min</a>(<a class="code" href="../../d1/d10/classcv_1_1MatExpr.html#a6dff8b6e9105b6d817b493e7be157c90">max</a>(out_, 0), out_size);</div><div class="line">        Mat out_img;</div><div class="line">        <a class="code" href="../../d8/d01/group__imgproc__color__conversions.html#ga397ae87e1288a81d2363b61574eb8cab">cvtColor</a>(img_out, out_img, <a class="code" href="../../d8/d01/group__imgproc__color__conversions.html#gga4e0972be5de079fed4e3a10e24ef5ef0a01a06e50cd3689f5e34e26daf3faaa39">COLOR_RGB2BGR</a>);</div><div class="line">        <span class="keywordtype">string</span> filename = filepath.substr(filepath.find_last_of(<span class="charliteral">&#39;/&#39;</span>)+1);</div><div class="line">        <span class="keywordtype">size_t</span> dotIndex = filename.find_last_of(<span class="charliteral">&#39;.&#39;</span>);</div><div class="line">        <span class="keywordtype">string</span> baseName = filename.substr(0, dotIndex);</div><div class="line">        <span class="keywordtype">string</span> ext = filename.substr(dotIndex+1, filename.length()-dotIndex);</div><div class="line">        <span class="keywordtype">string</span> calibratedFilePath = baseName + <span class="stringliteral">&quot;.calibrated.&quot;</span> + ext;</div><div class="line">        <a class="code" href="../../d4/da8/group__imgcodecs.html#gabbc7ef1aa2edfaa87772f1202d67e0ce">imwrite</a>(calibratedFilePath, out_img);</div></div><!-- fragment --><p>Save the calibrated image. </p>
</div></div><!-- contents -->
<!-- HTML footer for doxygen 1.8.6-->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated on Fri Apr 2 2021 11:36:39 for OpenCV by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="../../doxygen.png" alt="doxygen"/>
</a> 1.8.13
</small></address>
<script type="text/javascript">
//<![CDATA[
addTutorialsButtons();
//]]>
</script>
</body>
</html>
